package linkExcel;

import linkExcel.utils.ExcelUtils;
import linkExcel.utils.ReadTxtFile;
import linkExcel.utils.ToolUtils;
import org.apache.poi.common.usermodel.HyperlinkType;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.usermodel.Font;

import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 针对目标文件夹下所有文件保存至一个sheet
 */
public class WorkFilesMainGUI extends JFrame {

    private static String EXCEL_PATH;
    private static String SHEET_NAME;
    private static String BEGIN_PATH;

    private static final String CONFIG_PATH = "./config.txt";

    //父级禁止目录：比如选择名为app的文件夹，那么只会向下遍历一层
    private static String[] PARENT_DIRECTORY_PROHIBIT;

    //跳过的文件（模糊匹配）：比如想选择名为helloJson.txt的文件，可以输入lloJ作为关键匹配，这样该文件即可被跳过
    private static String[] FILE_IGNORE;

    private static boolean IS_HIDDEN_SHOW = false;

    private static List<String> ERROR_ITEMS = new ArrayList<>();

    private static Integer FILE_NUMS = 0;

    private static Integer DIRECTORY_NUMS = 0;

    private static Integer ROW_INDEX = 0;

    private List<JLabel> configs;

    public static void main(String[] args) {
        //加载配置文件
        WorkFilesMainGUI.loadDefaultConfig();
        //创建GUI
        SwingUtilities.invokeLater(() -> new WorkFilesMainGUI().OpenGUI());
    }

    private void OpenGUI() {
        JFrame frame = new JFrame("目录台账生成器 v0.20");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        // 创建一个面板，使用 BoxLayout
        Box box = Box.createVerticalBox();

        JPanel panel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        panel.add(new JLabel("<html><div style='color:red;font-size:11px'>正处于测试版本，超链逻辑是相对路径，不可跨盘加注</div></html>"));
        box.add(panel);

        panel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        panel.add(new JLabel("<html><div style='color:#7a797d;font-size:12px'>文件位置：</div></html>"));
        panel.add(changeSheetName("EXCEL_PATH"));
        box.add(panel);

        //换行
        panel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        panel.add(new JLabel("<html><div style='color:#7a797d;font-size:12px'>工作簿名：</div></html>"));
        panel.add(changeSheetName("SHEET_NAME"));
        box.add(panel);

        //换行
        panel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        panel.add(new JLabel("<html><div style='color:#7a797d;font-size:12px'>起始位置：</div></html>"));
        panel.add(changeSheetName("BEGIN_PATH"));
        box.add(panel);

        //换行
        panel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        String fileIgnore = "<html><div style='color:#7a797d;font-size:12px'>忽略文件：[";
        for (String s : FILE_IGNORE) {
            fileIgnore += s+";";
        }
        fileIgnore = fileIgnore.substring(0,fileIgnore.length()-1);
        fileIgnore+="]</div></html>";
        panel.add(new JLabel(fileIgnore));
        box.add(panel);

        panel = new JPanel(new FlowLayout(FlowLayout.LEFT));
        fileIgnore = "<html><div style='color:#7a797d;font-size:12px'>忽略父级（慎用）：[";
        for (String s : PARENT_DIRECTORY_PROHIBIT) {
            fileIgnore += s+";";
        }
        fileIgnore = fileIgnore.substring(0,fileIgnore.length()-1);
        fileIgnore+="]</div></html>";
        panel.add(new JLabel(fileIgnore));
        box.add(panel);

        //换行
        panel = new JPanel(new FlowLayout(FlowLayout.CENTER));
        panel.add(startGenerate("开始生成目录"));
        box.add(panel);

        // 创建一个固定大小的 JPanel，并将 Box 添加到这个 JPanel 中
        JPanel fixedPanel = new JPanel(null);
        fixedPanel.setPreferredSize(new Dimension(600, 250));
        fixedPanel.add(box);
        box.setBounds(0, 0, 600, 250);

        // 添加面板到主窗口
        frame.getContentPane().add(fixedPanel);

        // 设置窗口大小并显示
        frame.setSize(600, 300);
        frame.setResizable(false);
        frame.setLocationRelativeTo(null); // 居中显示
        frame.setVisible(true);

    }

    private JButton startGenerate(String btnStr) {
        JButton button = new JButton(btnStr);

        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent e) {
                //删除Excel
                ExcelUtils.delExcel(EXCEL_PATH);
                //打开或创建Excel
                Workbook workbook = ExcelUtils.createOrGetExcel(EXCEL_PATH, SHEET_NAME);
                //创建或选择sheet
                Sheet sheet = ExcelUtils.createOrGetSheet(workbook, SHEET_NAME);
                //遍历所有文件
                File file = new File(BEGIN_PATH);
                traverseFolder(file, 0, sheet, workbook);
                //打印错误结果
                System.out.println("共计[" + (DIRECTORY_NUMS + FILE_NUMS - ERROR_ITEMS.size()) + "/" + (DIRECTORY_NUMS + FILE_NUMS) + "]条。" + (ERROR_ITEMS.isEmpty() ? "超链加注全部成功" : "部分超链加注失败，失败内容如下"));
                if (!ERROR_ITEMS.isEmpty()) {
                    ERROR_ITEMS.forEach(System.out::println);
                }
                //存入Excel保存
                ExcelUtils.saveExcel(workbook, EXCEL_PATH);
                // 处理提交按钮点击事件，获取输入框内容并显示
                JOptionPane.showMessageDialog(new WorkFilesMainGUI(), "生成成功！" + "共计[" + (DIRECTORY_NUMS + FILE_NUMS - ERROR_ITEMS.size()) + "/" + (DIRECTORY_NUMS + FILE_NUMS) + "]条。" + (ERROR_ITEMS.isEmpty() ? "超链加注全部成功" : "部分超链加注失败，失败内容如下"));
            }
        });
        return button;
    }

    private JTextField changeSheetName(String parameter) {
        JTextField textField;
        switch (parameter) {
            case "BEGIN_PATH":
                textField = new JTextField(BEGIN_PATH, 40);
                break;
            case "EXCEL_PATH":
                textField = new JTextField(EXCEL_PATH, 40);
                break;
            case "SHEET_NAME":
                textField = new JTextField(SHEET_NAME, 40);
                break;
            default:
                return null;
        }
        textField.getDocument().addDocumentListener(new DocumentListener() {
            @Override
            public void insertUpdate(DocumentEvent e) {
                handleTextChange();
            }

            @Override
            public void removeUpdate(DocumentEvent e) {
                handleTextChange();
            }

            @Override
            public void changedUpdate(DocumentEvent e) {
                handleTextChange();
            }

            private void handleTextChange() {
                // 处理文本变化的逻辑
                switch (parameter) {
                    case "BEGIN_PATH":
                        BEGIN_PATH = textField.getText();
                        System.out.println(BEGIN_PATH);
                        break;
                    case "EXCEL_PATH":
                        EXCEL_PATH = textField.getText();
                        System.out.println(EXCEL_PATH);
                        break;
                    case "SHEET_NAME":
                        SHEET_NAME = textField.getText();
                        System.out.println(SHEET_NAME);
                        break;
                    default:
                        break;
                }
            }
        });
        return textField;
    }

    private static void loadDefaultConfig() {
        Map<String, String> map = new HashMap<>();
        try {
            FileInputStream fis = new FileInputStream(CONFIG_PATH);
            InputStreamReader isr = new InputStreamReader(fis, "UTF-8"); // 使用 UTF-8 编码读取
            BufferedReader br = new BufferedReader(isr);

            String line;
            while ((line = br.readLine()) != null) {
                if (line.contains("<:~:>")) {
                    String[] kv = line.split("<:~:>");
                    map.put(kv[0], kv[1]);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        EXCEL_PATH = map.get("EXCEL_PATH");
        SHEET_NAME = map.get("SHEET_NAME");
        BEGIN_PATH = map.get("BEGIN_PATH");
        if (map.get("PARENT_DIRECTORY_PROHIBIT") != null) {
            String directorys = map.get("PARENT_DIRECTORY_PROHIBIT");
            PARENT_DIRECTORY_PROHIBIT = directorys.split("-#_%-");
        }
        if (map.get("IS_HIDDEN_SHOW") != null) {
            IS_HIDDEN_SHOW = map.get("IS_HIDDEN_SHOW").equalsIgnoreCase("true");
        }
        if (map.get("FILE_IGNORE") != null) {
            String ignores = map.get("FILE_IGNORE");
            FILE_IGNORE = ignores.split("-#_%-");
        }
    }

    /**
     * 遍历文件夹下的所有文件
     *
     * @param folder   文件（夹）
     * @param colIndex
     * @param sheet
     * @param workbook
     * @return 文件vo对象集合
     */
    private static void traverseFolder(File folder, int colIndex, Sheet sheet, Workbook workbook) {
        //先做链接
        StringBuilder preStr = new StringBuilder();
        for (int i = 0; i < colIndex; i++) {
            if (i < colIndex - 1) {
                preStr.append("         ");
            } else if (i == colIndex - 1) {
                if (folder.isDirectory()) {
                    preStr.append(" ▼");
                } else {
                    preStr.append("🟠 ");
                }

            }
        }
        Row dataRow = sheet.createRow(ROW_INDEX++);
        sheet.setColumnWidth(0, 200 * 256);
        dataRow.createCell(0).setCellValue(preStr + folder.getName() + (folder.isDirectory() ? "" : (" [" + ToolUtils.formatFileSize(folder.length()) + "]")));
        CreationHelper creationHelper = workbook.getCreationHelper();
        Hyperlink hyperlink = creationHelper.createHyperlink(HyperlinkType.URL);
        try {
            hyperlink.setAddress(ToolUtils.getRelativePath(folder.getPath(), EXCEL_PATH));
            dataRow.getCell(0).setHyperlink(hyperlink);
            //样式
            CellStyle cellStyle = dataRow.getCell(0).getCellStyle();
            CellStyle newStyle = workbook.createCellStyle();
            newStyle.cloneStyleFrom(cellStyle);
            Font font = workbook.createFont();
            font.setColor(folder.isDirectory() ? IndexedColors.BLUE.getIndex() : IndexedColors.ORANGE.getIndex());
            newStyle.setFont(font);
            dataRow.getCell(0).setCellStyle(newStyle);
        } catch (Exception e) {
            ERROR_ITEMS.add(folder.getPath() + "--" + e.getCause());
        }
        //再递归
        if (folder.isDirectory()) {
            DIRECTORY_NUMS++;
            System.out.println("\uD83D\uDFE0文件夹：【" + folder.getName() + "】");
            // 获取文件夹内的文件和子文件夹
            File[] subFiles = folder.listFiles();
            if (subFiles != null) {
                for (File file : subFiles) {
                    // 跳过的父级内容
                    if (PARENT_DIRECTORY_PROHIBIT != null) {
                        boolean isJump = false;
                        for (String s : PARENT_DIRECTORY_PROHIBIT) {
                            if (folder.getParentFile().getName().equals(s)) {
                                isJump = true;
                                break;
                            }
                        }
                        if (isJump) {
                            continue;
                        }
                    }
                    //跳过的内容
                    if (FILE_IGNORE != null) {
                        boolean isJump = false;
                        for (String s : FILE_IGNORE) {
                            if (s.startsWith("%") && s.endsWith("%")) {
                                //全模糊
                                if (file.getName().contains(s.substring(1, s.length() - 1))) {
                                    isJump = true;
                                    break;
                                }
                                continue;
                            }
                            if (s.startsWith("%")) {
                                //前置模糊
                                if (file.getName().endsWith(s.substring(1))) {
                                    isJump = true;
                                    break;
                                }
                            } else if (s.endsWith("%")) {
                                //后置模糊
                                if (file.getName().startsWith(s.substring(0, s.length() - 1))) {
                                    isJump = true;
                                    break;
                                }
                            } else {
                                //硬匹配
                                if (file.getName().equals(s)) {
                                    isJump = true;
                                    break;
                                }
                            }
                        }
                        if (isJump){
                            continue;
                        }
                    }
                    if(!IS_HIDDEN_SHOW){
                        if (file.isHidden()){
                            continue;
                        }
                    }
                    traverseFolder(file, colIndex + 1, sheet, workbook);
                }
            }
        } else {
            FILE_NUMS++;
        }
    }
}
